package com.hbnu.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import static com.hbnu.tools.PrintTool.print;
import static com.hbnu.tools.PrintTool.println;
import static com.hbnu.tools.ScannerTool.nextLine;

public class FileTool {

    //获取文件后缀
    public static String getFileExtension(File file) {
        if (file == null) {
            return "";
        }

        String fileName = file.getName();
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex == -1) {
            return ""; // 没有后缀名
        }
        return fileName.substring(dotIndex + 1).toLowerCase();
    }
    //计数md5
    public static String calculateMD5(File file)  {
        // 创建 MessageDigest 实例，指定 MD5 算法
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        // 读取文件并计算哈希
             try (FileInputStream fis = new FileInputStream(file);
                  DigestInputStream dis = new DigestInputStream(fis, md)) {
                    byte[] buffer = new byte[1024];
                    while (dis.read(buffer) != -1) {
                        // 读取文件的同时更新哈希值
                    }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }

        // 获取计算出的 MD5 值
        byte[] hashBytes = md.digest();

        // 将字节数组转换为十六进制字符串
        StringBuilder sb = new StringBuilder();
        for (byte b : hashBytes) {
            sb.append(String.format("%02x", b));
        }

        return sb.toString();  // 返回文件的 MD5 哈希值
    }

    //计算IP
    public static String getIP() {
        InetAddress inetAddress;
        try {
            inetAddress = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
        // 获取本机的 IP 地址
        return inetAddress.getHostAddress();
    }

    //判断给定的字符串是否为有效的 IP 地址。
    public static boolean isValidIPAddress(String ip) {
        try {
            // 尝试将字符串解析为 InetAddress
            InetAddress address = InetAddress.getByName(ip);
            // 检查是否为 IP 地址（而不是主机名）
            return address.getHostAddress().equals(ip);
        } catch (UnknownHostException e) {
            PrintTool.println("无效IP");
            // 如果抛出 UnknownHostException，则表示不是一个有效的 IP 地址
            return false;
        }
    }

    //文件大小显示
    public static String formatFileSize(long size) {
        final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
        int unitIndex = 0;
        double remainingSize = size;

        while (remainingSize >= 1024 && unitIndex < units.length - 1) {
            remainingSize /= 1024;
            unitIndex++;
        }

        return String.format("%.2f %s", remainingSize, units[unitIndex]);
    }

    //判断文件存在并且是文件夹
    public static boolean existsAndIsFolder(File file){
        //判断接收文件的用户家是否有效
        if (!file.exists()) {
            print("本地文件夹:\t"+file.getAbsolutePath()+"\t不存在,是否创建(y/n)");
            if (nextLine().equalsIgnoreCase("Y")) {
                boolean isCreated = file.mkdirs();
                if (!isCreated) {
                    println("创建失败！");return false;
                }
            }
            return false;
        }
        if(file.isFile()){
            println("不是文件夹！");
            return false;
        }
        return true;
    }

    //判断文件名是否存在
    public static boolean existsFileName(String path,String name){
        File file = new File(path);
        //判断文件下是否存在了
        File[] files = file.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.getName().equals(name)) {
                    println("文件夹下有同名文件！");
                    return true;
                }
            }
        }
        return false;
    }

    //文件取唯一名
    public static String getUniqueFileName(String filePath) {
        File file = new File(filePath);

        // 如果文件不存在，则直接返回原路径
        if (!file.exists()) {
            return filePath;
        }

        // 获取文件的父目录和原始文件名
        String parentDir = file.getParent();
        String fileName = file.getName();

        // 获取文件的基本名称和扩展名
        int dotIndex = fileName.lastIndexOf('.');
        String baseName = (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
        String extension = (dotIndex == -1) ? "" : fileName.substring(dotIndex);

        // 生成新文件名
        int count = 1;
        String newFileName;
        File newFile;

        // 循环检查生成的新文件名是否已经存在
        do {
            newFileName = baseName + "_" + count + extension;
            newFile = new File(parentDir, newFileName);
            count++;
        } while (newFile.exists());

        // 返回新的文件路径
        return newFile.getAbsolutePath();
    }

    //计算文件夹大小，空间考虑
    public static long calculateFolderSize(File file)  {
        try {
            Path folderPath = Paths.get(file.getAbsolutePath());
            final long[] size = {0}; // 使用数组来允许在 lambda 表达式中修改
            Files.walkFileTree(folderPath, new SimpleFileVisitor<>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                    size[0] += attrs.size();
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFileFailed(Path file, IOException exc) {
                    // 如果无法访问某个文件，忽略它
                    return FileVisitResult.CONTINUE;
                }
            });
            return size[0];
        } catch (IOException e) {
            throw new RuntimeException("计算本地文件大小异常");
        }
    }


}
